2012/12/21

Recent entries from same category

  1. Ruby の Array#<< は Array#push よりも速いか
  2. Ruby の a = a + 1 はなぜ undefined method '+' for nil:NilClass なのか
  3. Re: Ruby 製バッチ処理を省メモリ化した
  4. Crystal と CRuby でHTTPサーバのベンチマーク
  5. pure mruby な JSON パーサ書いた。

トピックス
  • mrbgems が入った
  • お前はどこのワカメじゃ
  • ビルド方法が変わった
  • mruby-uv mruby-http mruby-sinatic
  • mruby-json
  • mruby-sqlite3
  • mruby-curl
  • そして mruby-v8

mrbgems が入った

mruby に GEM っぽい物が入った。
とは言ってもスタティックリンクなのでダイナミックローディングしてくれる訳じゃない。
しかしながらパッケージを導入する上での取り決めが決まりつつあると言った感じ。
使うには MRUBY_ROOT という環境変数を mruby のリポジトリトップに設定しておき、MAKEFILE_4_GEM$MRUBY/mrbgems/Makefiel4gem にしておくと良い。後者は要らなくなったかもしれない。
具体的には $MRUBY_ROOT/mrbgems/GEMS.active というファイルに使う mrbgems のフォルダを一覧しておくとビルドの際に一緒にビルドおよびリンクしてくれるという物。
$MRUBY_ROOT/mrbgems/g の下に置く場合は絶対パスではなくフォルダ名だけで良い。
mrbgems には大きく2つあって、C言語で書く拡張と、ruby 形式で書く物がある。後者はビルド時にバイナリ化されてリンクされる。
C言語で書く際のお手本としては mruby-md5 が良いと思う。

お前はどこのワカメじゃ

mrbgems は bovi という人がパッチ書いて取り込まれたのだけど、既存の拡張をどうやって mrbgems 化するか聞いてたら「やってあげる」という神キタコレな運びとなって mruby-md5 を mrbgems 化して貰えた。その時の出来事が彼のブログに載っているのだが
mrbgems in HEAD - mruby.sh
http://mruby.sh/201212101231.html
assert('MD5 Hash for old example'do
  MD5::md5_hex('お前はどこのワカメじゃ') == "43820f48a8506c8e2fae6f8558971920"
end
まさか誰も僕のソースなんか見ないだろうと思って書いてたコードを使ってテストにしてくれました。恥ずかしい...

ビルド方法が変わった

ここ最近の大きな変更。
これまでは Makefile もしくは cmake でビルドしていたけど、CRuby と minirake というスクリプトを使ってビルドする仕組みが入りました。現在のルートにある Makefile はこれを呼び出しているだけです。

mruby-uv mruby-http mruby-sinatic

以前から作ってましたが、Matz さんにアドバイスを貰って安定動作する様になりました。

https://github.com/mattn/mruby-uv
https://github.com/mattn/mruby-http
https://github.com/mattn/mruby-sinatic

Windows のしょぼいマシンでもちょっとしたHTTPサーバ(example/server.rb)で 4000 req/sec は出ます。
mruby-sinatic はコレを mrbgems 化した物です。

mruby-json

以前から JSON パーサが欲しかったので自分で書きました。

https://github.com/mattn/mruby-json

内部では parson を使ってます。
2時間程度で作った物でメモリ開放漏れてましたが...

mruby-sqlite3

こちらも自分で...

https://github.com/mattn/mruby-sqlite3

db = SQLite3::Database.new('foo.db')
db.execute('select * from foo'do |rowfields|
  puts row
end

row = db.execute('select * from bar')
puts row.fields()
while !row.eof?
  puts row.next()
end
row.close()
こんな風に使います。

mruby-curl

proxy 超えられて SSL も使える HTTP クライアントが欲しかったので書いた。

https://github.com/mattn/mruby-curl

個人的にはかなり便利になった思う。
HTTP::Response を返すので mruby-http が必要。
mruby-json と mruby-curl を使って Gist をポストしてみました。 #!mruby

if ARGV.size != 1
  raise "gist.rb [GIST_TOKEN]"
end

req = HTTP::Request.new
req.method = "POST"
req.body = JSON::stringify({
  "description"=> "We love mruby!",
  "public"=> true,
  "files"=> {
    "file1.txt"=> {
      "content"=> "mruby is awesome!"
    }
  }
})
req.headers['Authorization'] = "token #{ARGV[0]}"
req.headers['Content-Type'] = "application/json"
Curl::SSL_VERIFYPEER = 0
res = Curl::send("https://api.github.com/gists", req)
puts JSON::parse(res.body)['html_url']
ポストされた物がこちら。
We love mruby!

#!mruby if ARGV . size != 1 raise "gist.rb [GIST_TOKEN]" end req = HTTP : :Request . new req . metho...

https://gist.github.com/4342903

そして mruby-v8

そしてそろそろ誰も得しない物が作りたくなってくる悪い病気が。

https://github.com/mattn/mruby-v8

mruby から javascript が呼べ、そしてその javascript から mruby が呼べる!
#!mruby

v8 = V8.new
puts v8.eval('1+2')

v8.add_func("plus"do |lhs,rhs|
  lhs + rhs
end

puts v8.eval("plus(2,3)")
すばらしいですね!便利って言え

まとめ

mruby 面白いよ!みんなも mrbgems 作って遊びましょう!

追記
@matsumotory さんがちゃくちゃくと mruby 内臓ウォシュレット計画をすすめている。
人間とウェブの未来 - mruby-zabbixとmruby-growthforecastでデバイスやアプリケーションの監視並びに情報の可視化を実現
http://blog.matsumoto-r.jp/?p=3168

Posted at by